package phototagger.imgsim;

import java.util.Collection;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Iterator;

/** A container for Coeffients. Coeffients are normally stored in 2D
    arrays as doubles, but we need to be able to find the N largest coeffients,
    which is troublesome in a 2D array, and really easy in a List. 
    Contains a method for sorting the CoeffientList (outsourced to 
    Collections.sort). After they're sorted inside the CoeffientList, 
    the x and y positions are used by <code>reassemble</code> to put the 
    coeffients back into a 2D array.
    
    @see Coeffient
**/

public class CoeffientList {
	
    private int numCols;
    private int numRows;
    private ArrayList list = new ArrayList();
    
    /** Makes a new CoeffientList.
	@param coef the 2D array of Coeffients
    **/
    CoeffientList(double[][] coef) {
	numCols = (coef[0]).length;
	numRows = coef.length;
	
	for(int y=0; y < numRows; y++) {
	    for(int x=0; x < numCols; x++) {
		add(new Coeffient(coef[y][x], x, y));
	    }
	}
    }
    
    /** A type-aware wrapper for ArrayList.add 
	@param c a single Coeffient 
    **/
    public void add(Coeffient c) {
	list.add(c);
    }
    
    /** Sorts the CoeffientList. A wrapper for Collections.sort. **/
    public void sort() {
	Collections.sort(list);
    }
    
    /** Puts back together an array of coeffients from their CoeffientList
	representation. 
	@returns a 2D array of coeffients, reassembled from their
	CoeffientList representation 
    **/
    public double[][] reassemble() {
	double[][] reassembled = new double[numRows][numCols];
	Iterator it = list.iterator();
	while(it.hasNext()) {
	    Coeffient current = (Coeffient)it.next();
	    reassembled[current.ypos][current.xpos] = current.value;
	}
	
	return reassembled;
    }
    
    public double[][] getLargest(int largest) {
	if(largest > list.size()) {
	    String m = "largest coeffients to get (" + largest +") " +
		"was longer than the length of the list!";
	    throw new IllegalArgumentException(m);
	}

	// remove all but the 'largest' elements of the list
	//System.out.println("unsorted list " + list);
	Collections.sort(list);
	//System.out.println("sorted list " + list);
	
	class ArrayListWrapper extends ArrayList {
	    public ArrayListWrapper(Collection c) { super(c); }
	    public void removeRange(int start, int end) { super.removeRange(start, end); }
	}	
	ArrayListWrapper lamelist = new ArrayListWrapper(list);
	lamelist.removeRange(0, lamelist.size() - largest);

	//	assert lamelist.size() == largest;
	
	list = (ArrayList)lamelist;
	// put the array back together and return it
	return reassemble();
    }
}
